
'''

'''

import operator
import types
import sys

def named_tuple(classname, fieldnames):
    # Populate a dictionary of field property accessors
    cls_dict = { name: property(operator.itemgetter(n))
                for n, name in enumerate(fieldnames) }

    # Make a __new__ function and add to the class dict
    def __new__(cls, *args):
        if len(args) != len(fieldnames):
            raise TypeError('Expected {} arguments'.format(len(fieldnames)))
        return tuple.__new__(cls, args)

    cls_dict['__new__'] = __new__

    # Make the class
    cls = types.new_class(classname, (tuple,), {},
                        lambda ns: ns.update(cls_dict))

    # Set the module to that of the caller 获取调用者的模块名
    cls.__module__ = sys._getframe(1).f_globals['__name__']
    return cls

def recipe1():
    point = named_tuple('Point', ['x', 'y'])
    print(f"{point = }")
    print(f"{type(point) = }")

    p = point(4, 5)

    print(f"{len(p) = }")
    print(f"{p.x = }")
    print(f"{p.y = }")
    print('%s %s' % p)

    try:
        p.x = 2
    except AttributeError as e:
        print(e)     

def main():
    print('recipe1'.center(20, '*'))
    recipe1()

if __name__ == '__main__':
    main()                